package com.baidu.ota.presenter;

import android.content.Context;
import android.os.Handler;

import com.baidu.commonlib.interfaces.IDownloadListenerEx;
import com.baidu.commonlib.interfaces.IOtaAgent;
import com.baidu.commonlib.interfaces.IUpgradeListener;
import com.baidu.ota.R;
import com.baidu.ota.model.IOtaModel;
import com.baidu.ota.model.OtaModelImpl;
import com.baidu.ota.utils.RecoveryUtil;
import com.baidu.ota.view.IUpgradeView;

public class UpgradePresenterImpl implements IUpgradePresenter {
    private final IOtaModel model;
    private final IUpgradeView view;
    private final Handler handler;
    private long startTime = 0;

    UpgradePresenterImpl(IOtaAgent agent, IUpgradeView view) {
        this.model = new OtaModelImpl(agent);
        this.handler = new Handler();
        this.view = view;
    }

    @Override
    public void download(String pkg) {
        startTime = System.currentTimeMillis();
        view.showProgressText(view.getContext().getString(R.string.establishing_connection));
        model.download(pkg, new DownloadListener(view));
    }

    @Override
    public void cancelDownload(String pkg) {
        model.cancelDownload(pkg);
    }

    @Override
    public void upgrade(String pkg) {
        model.upgrade(pkg, new UpgradeListener(view));
    }

    @Override
    public void reboot(Context context) {
        RecoveryUtil.reboot2Recovery(context);
    }

    private void waitFor(final Runnable runnable) {
        final long diff = System.currentTimeMillis() - startTime;
        long wait = diff < 1000 ? 1000 - diff : 0;
        handler.postDelayed(runnable, wait);
    }

    private class DownloadListener implements IDownloadListenerEx {
        private final IUpgradeView view;
        private int state = STATE_INIT;

        DownloadListener(IUpgradeView v) {
            view = v;
        }

        @Override
        public void onPending(String s) {
            // ignore
        }

        @Override
        public void onPrepare(String s) {
            state = IUpgradePresenter.STATE_INIT;
        }

        @Override
        public void onProgress(String s, long soFar, long total) {
            double percent = soFar * 1.0f / total * 100;
            int progress = (int) (percent);
            view.onDownloadProgress(progress);

            if (state != IUpgradePresenter.STATE_DOWNLOADING) {
                state = IUpgradePresenter.STATE_DOWNLOADING;
                view.onStateChanged(state);
            }
        }

        @Override
        public void onPaused(String s) {
            view.onDownloadPaused();

            state = IUpgradePresenter.STATE_DOWNLOAD_PAUSED;
            view.onStateChanged(state);
        }

        @Override
        public void onFailed(String s, final int i, final String s1) {
            waitFor(new Runnable() {
                @Override
                public void run() {
                    view.onDownloadFail(i, s1);
                    state = IUpgradePresenter.STATE_DOWNLOAD_FAIL;
                    view.onStateChanged(IUpgradePresenter.STATE_DOWNLOAD_FAIL);
                }
            });
        }

        @Override
        public void onFinished(String s) {
            view.onDownloadSuccess();

            state = IUpgradePresenter.STATE_DOWNLOAD_SUCCESS;
            view.onStateChanged(IUpgradePresenter.STATE_DOWNLOAD_SUCCESS);
        }

        @Override
        public void onReplaced(String pkgName) {
            // ignored
        }
    }

    private static class UpgradeListener implements IUpgradeListener {
        private final IUpgradeView view;
        private int state = STATE_INIT;

        UpgradeListener(IUpgradeView v) {
            view = v;
        }

        @Override
        public void onProgress(String s, String s1, int i) {
            view.onUpgradeProgress(i);
            if (state != IUpgradePresenter.STATE_UPGRADING) {
                state = IUpgradePresenter.STATE_UPGRADING;
                view.onStateChanged(state);
            }
        }

        @Override
        public void onFailed(String s, int i, String s1) {
            view.onUpgradeFail(i, s1);

            state = IUpgradePresenter.STATE_UPGRADE_FAIL;
            view.onStateChanged(state);
        }

        @Override
        public void onWriteDone(String s) {
            view.onUpgradeWriteDone();

            state = IUpgradePresenter.STATE_UPGRADE_WRITE_DONE;
            view.onStateChanged(state);
        }

        @Override
        public void onSuccess(String s) {
            view.onUpgradeSuccess();

            state = IUpgradePresenter.STATE_UPGRADE_SUCCESS;
            view.onStateChanged(state);
        }
    }
}
